package org.hako.recite.word.test.impl.gui.swing;

import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

import org.hako.recite.word.gui.swing.AbstractReciteWordFrame;
import org.hako.recite.word.test.WordTestMode;
import org.hako.recite.word.test.WordTestProfile;
import org.hako.recite.word.test.impl.gui.NullWordTestBehavior;
import org.hako.recite.word.test.impl.gui.WordTestBehavior;

/**
 * Frame of word test settings. The settings will put into
 * {@link WordTestProfile}.
 * 
 * @since 0.4.2
 * @author <a href="mailto:xnnyygn@gmail.com">xnnyygn</a>
 */
public class WordTestSettingFrame extends AbstractReciteWordFrame {

	private WordTestBehavior behavior;
	private JTextField tfWordOffset;
	private JTextField tfRangeStart;
	private JTextField tfRangeEnd;
	private JComboBox cbTestMode;
	private JTextField tfWordLimit;
	private JTextField tfQuestionFieldIndex;
	private JTextField tfAnswerFieldIndex;

	/**
	 * Create
	 */
	public WordTestSettingFrame() {
		this(new NullWordTestBehavior(), new WordTestProfile());
	}

	/**
	 * Create
	 * 
	 * @param behavior
	 * @param profile
	 *            initial profile
	 */
	public WordTestSettingFrame(WordTestBehavior behavior,
			WordTestProfile profile) {
		super("Word Test Settings");
		this.behavior = behavior;
		frame.setResizable(false);
		JPanel panel = new JPanel();
		panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

		// initialize component
		addComponentsToPane(panel, profile);
		updateComponents(profile.getTestMode());
		frame.add(panel);
		frame.pack();
		
		// center frame
		centerInScreen();
	}

	/**
	 * Add components to pane.
	 * 
	 * @param container
	 * @param profile
	 */
	private void addComponentsToPane(Container container,
			WordTestProfile profile) {
		int row = 0;
		container.setLayout(new GridBagLayout());

		createTitleAndAddToPane(container, row);
		row++;

		// add label test mode
		container.add(new JLabel("Test mode"), createLabelConstraints(row));

		// add select test mode
		cbTestMode = new JComboBox(WordTestMode.values());
		cbTestMode.setPreferredSize(new Dimension(200, 20));
		cbTestMode.addItemListener(new ItemListener() {

			@Override
			public void itemStateChanged(ItemEvent e) {
				updateComponents((WordTestMode) e.getItem());
			}
		});
		cbTestMode.setSelectedItem(profile.getTestMode());
		container.add(cbTestMode, createRightSideConstraints(row));
		row++;

		// add label word limit
		container.add(new JLabel("Word limit"), createLabelConstraints(row));

		// add text field word limit
		tfWordLimit = new JTextField(String.valueOf(profile.getWordLimit()));
		container.add(tfWordLimit, createRightSideConstraints(row));
		row++;

		// add label word offset
		container.add(new JLabel("Word start"), createLabelConstraints(row));

		// add text field word offset
		tfWordOffset = new JTextField(String.valueOf(profile.getWordOffset()));
		container.add(tfWordOffset, createRightSideConstraints(row));
		row++;

		// add label range start
		container.add(new JLabel("Range start"), createLabelConstraints(row));

		// add text field range start
		tfRangeStart = new JTextField(String.valueOf(profile
				.getWordRangeStart()));
		container.add(tfRangeStart, createRightSideConstraints(row));
		row++;

		// add label range end
		container.add(new JLabel("Range end"), createLabelConstraints(row));

		// add text field range end
		tfRangeEnd = new JTextField(String.valueOf(profile.getWordRangeEnd()));
		container.add(tfRangeEnd, createRightSideConstraints(row));
		row++;

		// add label question field index
		container.add(new JLabel("Question label index"),
				createLabelConstraints(row));

		// add text field question field index
		// TODO replace with field select
		tfQuestionFieldIndex = new JTextField(String.valueOf(profile
				.getQuestionFieldIndex()));
		container.add(tfQuestionFieldIndex, createRightSideConstraints(row));
		row++;

		// add label answer field index
		container.add(new JLabel("Answer label index"),
				createLabelConstraints(row));

		// add text field question field index
		// TODO replace with field select
		tfAnswerFieldIndex = new JTextField(String.valueOf(profile
				.getAnswerFieldIndex()));
		container.add(tfAnswerFieldIndex, createRightSideConstraints(row));
		row++;

		createStartAndAddToPane(container, row);
	}

	/**
	 * Create title label and add to pane.
	 * 
	 * @param container
	 * @param row
	 */
	private void createTitleAndAddToPane(Container container, int row) {
		GridBagConstraints c = new GridBagConstraints();
		c.gridx = 0;
		c.gridy = row;
		c.gridwidth = 2;
		c.insets = new Insets(0, 0, 6, 0);

		// add label title
		JLabel lbTitle = new JLabel("Settings of word test");
		container.add(lbTitle, c);
	}

	/**
	 * Create start button and add to pane.
	 * 
	 * @param container
	 * @param row
	 */
	private void createStartAndAddToPane(Container container, int row) {
		GridBagConstraints c = new GridBagConstraints();
		c.gridx = 1;
		c.gridy = row;
		c.anchor = GridBagConstraints.LINE_START;
		JButton btnStart = new JButton("Start");
		btnStart.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {

				// build word test profile
				WordTestProfile profile = new WordTestProfile();
				WordTestMode testMode = (WordTestMode) cbTestMode
						.getSelectedItem();
				profile.setTestMode(testMode);
				profile.setWordLimit(Integer.parseInt(tfWordLimit.getText()));
				switch (testMode) {
				case LEARNING:
					profile.setWordOffset(Integer.parseInt(tfWordOffset
							.getText()));
					break;
				case TEST:
					profile.setWordRangeStart(Integer.parseInt(tfRangeStart
							.getText()));
					profile.setWordRangeEnd(Integer.parseInt(tfRangeEnd
							.getText()));
					break;
				}
				profile.setQuestionFieldIndex(Integer
						.parseInt(tfQuestionFieldIndex.getText()));
				profile.setAnswerFieldIndex(Integer.parseInt(tfAnswerFieldIndex
						.getText()));

				// show word test frame
				behavior.showTestWindow(profile);
			}
		});
		container.add(btnStart, c);
	}

	/**
	 * Create constraints of right side.
	 * 
	 * @param row
	 * 
	 * @return
	 */
	private GridBagConstraints createRightSideConstraints(int row) {
		GridBagConstraints c = new GridBagConstraints();
		c.fill = GridBagConstraints.HORIZONTAL;
		c.gridx = 1;
		c.gridy = row;
		c.weightx = 1.0d;
		c.insets = new Insets(0, 3, 3, 0);
		return c;
	}

	/**
	 * Create constraints of left side.
	 * 
	 * @param row
	 * @return
	 */
	private GridBagConstraints createLabelConstraints(int row) {
		GridBagConstraints c = new GridBagConstraints();
		// c.fill = GridBagConstraints.HORIZONTAL;
		c.gridx = 0;
		c.gridy = row;
		// c.weightx = 0.5d;
		c.anchor = GridBagConstraints.LINE_END;
		c.insets = new Insets(0, 0, 3, 3);
		return c;
	}

	/**
	 * Update components.
	 * 
	 * @param mode
	 */
	private void updateComponents(WordTestMode mode) {
		switch (mode) {
		case LEARNING:
			tfRangeStart.setEnabled(false);
			tfRangeEnd.setEnabled(false);
			tfWordOffset.setEnabled(true);
			break;
		case TEST:
			tfRangeStart.setEnabled(true);
			tfRangeEnd.setEnabled(true);
			tfWordOffset.setEnabled(false);
			break;
		}
	}
}
